﻿using Client.Command;
using Client.MirNetwork;
using Client.MirObjects;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Client.MirScenes.Dialogs
{
    public partial class HangDialog : Form
    {
        #region HangUpSetting
        public long MpTime = 0;
        public long HpTime = 0;
        public long DrugTime = 0;
        public long PracticeTime = 0;
        public long LastNoticeTime = 0;
        public long HangTime = 0;

        public bool CanPick = true;
        public long CanPickTime = 0;

        public bool ToPick = false;
        public long ToPickTime = 0;


        public long PracticeBetween = 2000;
        public static int[] DotAttact = new int[] {3,6,18,38,34,23,57,64,70 };
        public static List<String> WhiteName = new List<String>();
        internal HangUpCmd hangUpCmd = new HangUpCmd();
        public int[] HpIndex = new int[] { 658, 660, 662, 664, 666 };
        public int[] MpIndex = new int[] { 659, 661, 663, 665, 667 };
        public int[] RescueIndex = new int[] { 670, 671, 672, 673 };
        public string[] _pickItemName = new string[] {"金币","太阳水","强效太阳水","千年雪霜","万年雪霜","银蛇","魔杖","天珠项链","铂金戒指","金戒指","降妖除魔戒指","道术守护石(小)", "道术守护石(大)","比奇通用币","祝福油","攻击药水" };
        public string[] PickItemName
        {
            get => _pickItemName;
        }

        #endregion
        public MapObject ToAttactObject = null;
        public bool AutoAttack
        {
            get { return hangUpCk.Checked; }
            set
            {
                ToAttactObject = null;
                if (hangUpCk.Checked == value)
                    return;
                hangUpCk.Checked = value;
                if (GameScene.Scene != null)
                {
                    GameScene.Scene.ChatDialog.ReceiveChat(value ? "[测试自动攻击: 开启]" : "[测试自动攻击: 关闭]", ChatType.Hint);
                    if (hangUpCk.Checked == true)
                    {
                        HangUpPoint = GameScene.User.CurrentLocation;
                        this.Text = HangUpPoint.ToStr();
                    }
                }
            }
        }
        public bool AutoPractice
        {
            get { return autoPractice.Checked; }
            set { autoPractice.Checked=value; }
        }

        public long MagicTime = 0;
        public bool UseMagic
        {
            get { return checkBox1.Checked; }
            set { checkBox1.Checked = value; }
        }
        public bool AutoMed
        {
            get { return autoMedCk.Checked; }
            set { autoMedCk.Checked = value; }
        }
        public bool AutoDrug
        {
            get { return autoDrugCk.Checked; }
            set
            {
                autoDrugCk.Checked = value;
            }
        }
        public bool PickAdded => pickUpgrade_ck.Checked;

        private long AmoreTime=0;
        public bool AutoAmore
        {
            get { return autoAmoreCk.Checked; }
            set
            {
                autoAmoreCk.Checked = value;
            }
        }
        private long MineTime = 0;
        public bool AutoMine
        {
            get { return autoMineCk.Checked; }
            set
            {
                autoMineCk.Checked = value;
            }
        }
        public double DangerMp
        {
            get
            {
                var re = new Regex("(\\d{1,3})%{0,1}");
                if(re.IsMatch(dangerMp.Text))
                {
                    var match = re.Match(dangerMp.Text);
                    if(dangerMp.Text.EndsWith("%"))
                    {
                        double d1 = Int32.Parse(match.Groups[1].Value);
                        if(d1>0&&d1<100)
                        {
                            return d1 / 100;
                        }
                        else
                        {
                            return 0.3;
                        }
                    }
                    else
                    {
                        double d1 = Int32.Parse(match.Groups[1].Value);
                        if (d1 <= 0)
                            return 10;
                        return d1;
                    }
                }
                else
                {
                    return 60;
                }
            }
        }

        public double DangerHp
        {
            get
            {
                var re = new Regex("(\\d{1,3})%{0,1}");
                if (re.IsMatch(dangerHp.Text))
                {
                    var match = re.Match(dangerHp.Text);
                    if (dangerHp.Text.EndsWith("%"))
                    {
                        double d1 = Int32.Parse(match.Groups[1].Value);
                        if (d1 > 0 && d1 < 100)
                        {
                            return d1 / 100;
                        }
                        else
                        {
                            return 0.3;
                        }
                    }
                    else
                    {
                        double d1 = Int32.Parse(match.Groups[1].Value);
                        if (d1 <= 0)
                            return 10;
                        return d1;
                    }
                }
                else
                {
                    dangerHp.Text=(GameScene.User.MaxHP / 2).ToString();
                    return GameScene.User.MaxHP/2;
                }
            }
        }

        public double RescueHp
        {
            get
            {
                var re = new Regex("(\\d{1,3})%{0,1}");
                if (re.IsMatch(rescueHp.Text))
                {
                    var match = re.Match(rescueHp.Text);
                    if (rescueHp.Text.EndsWith("%"))
                    {
                        double d1 = Int32.Parse(match.Groups[1].Value);
                        if (d1 > 0 && d1 < 100)
                        {
                            return d1 / 100;
                        }
                        else
                        {
                            return 0.3;
                        }
                    }
                    else
                    {
                        double d1 = Int32.Parse(match.Groups[1].Value);
                        if (d1 <= 0)
                            return 10;
                        return d1;
                    }
                }
                else
                {
                    rescueHp.Text = (GameScene.User.MaxHP / 5).ToString();
                    return GameScene.User.MaxHP /5;
                }
            }
        }
        private static Point _hangUpPoint;
        public static Point HangUpPoint
        {
            get => _hangUpPoint;
            set
            {
                _hangUpPoint = value;
                GameScene.Scene.ChatDialog.ReceiveChat("挂机原点坐标" + _hangUpPoint.ToStr(), ChatType.Hint);
            }
        }
        private static InIReader Reader;
        public HangDialog()
        {
            InitializeComponent();

            this.Location = new Point(GameScene.Scene.Location.X,GameScene.Scene.Location.Y);
            this.TopMost = true;
            var texts=String.Join("\r\n", _pickItemName);
            richTextBox2.Text = texts;
            //    string configPath = @".\Config\" + GameScene.User.Name;
            //    Reader = new InIReader(configPath);
            //    if (!File.Exists(configPath))
            //    {
            //        File.Create(configPath);
            //        Save();
            //        return;
            //    }
            //    Load();
        }

        public void Load()
        {
            var User = GameScene.User;
            dangerHp.Text= Reader.ReadString("Hang", "DangerHp",User.MaxHP/2+"");
            dangerMp.Text = Reader.ReadString("Hang", "DangerMp", User.MaxMP / 2+ "");
            rescueHp.Text = Reader.ReadString("Hang", "DangerHp2", User.MaxHP / 5 + "");
            maskedTextBox1.Text = Reader.ReadString("Hang", "PracticeBetween", "2");
        }

        public void Save()
        {
            Reader.Write("Hang", "DangerHp", DangerHp);
            Reader.Write("Hang", "DangerMp", DangerMp);
            Reader.Write("Hang", "DangerHp2", DrugTime);
            Reader.Write("Hang", "PracticeBetween", PracticeBetween);
        }

        public void Process()
        {
            if(AutoPractice && PracticeTime < CMain.Time)
            {
                PracticeTime = CMain.Time + PracticeBetween;
                    hangUpCmd.AutoPractice();
            }
            if (AutoMed)
                hangUpCmd.AutoMed(this);
            if(AutoAmore)
            {
                if (AutoAmore && AmoreTime < CMain.Time)
                {
                    AmoreTime = CMain.Time + 2000;
                    hangUpCmd.AutoAmore();
                }
            }
            if(AutoMine)
            {
                if (AutoMine && MineTime < CMain.Time)
                {
                    MineTime = CMain.Time + 5000;
                    hangUpCmd.AutoMine();
                }
            }
            if (AutoAttack)
            {
                if (AutoDrug && DrugTime < CMain.Time)
                {
                    DrugTime = CMain.Time + 2000;
                    hangUpCmd.AutoDrug();
                }
                if(UseMagic&&MagicTime<CMain.Time)
                {
                    MagicTime = CMain.Time + 1000;
                    hangUpCmd.AutoMagic();

                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.Visible = false;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            WhiteName.Clear();
            foreach(var str in richTextBox1.Lines)
            {
                if (!String.IsNullOrWhiteSpace(str))
                    WhiteName.Add(str);
            }
        }

        private void maskedTextBox1_TextChanged(object sender, EventArgs e)
        {
            PracticeBetween = Int32.Parse(maskedTextBox1.Text) * 1000;
        }
        private List<NodeD> CurrentPath;

        public void HangUpPath()
        {

            if (!GameScene.Scene.HangDialog.AutoAttack || MapObject.TargetObject != null)
            {
                return;
            }
            try
            {
                //Console.WriteLine("找攻击目标开始");
                if (CurrentPath == null || CurrentPath.Count == 0)
                {
                    hangUpCmd.HangUpPath = false;
                }
                
                if (hangUpCmd.HangUpPath && HangUpCmd.IsValidTarget(ToAttactObject)&& LastNoticeTime < CMain.Time)
                    return;
                var User = GameScene.User;

                if (HangUpCmd.IsValidTarget(ToAttactObject))
                {
                    var targetDis = Functions.ManhattanDistance(User.CurrentLocation, ToAttactObject.CurrentLocation);
                    if (LastNoticeTime < CMain.Time)
                    {
                        GameScene.Scene.ChatDialog.ReceiveChat(String.Format("距离播报，目标{0}，坐标{1},{2}，距离{3}", ToAttactObject.Name, ToAttactObject.CurrentLocation.X, ToAttactObject.CurrentLocation.Y, targetDis), ChatType.Hint);
                    }
                    LastNoticeTime = CMain.Time + 2000;
                    if (targetDis < 14)//目标距离14以内，不对其他怪物判断
                    {
                        if (targetDis <3)//目标距离2以内，变为目标
                        {
                            MapObject.TargetObject = GameScene.Scene.HangDialog.ToAttactObject;
                            GameScene.Scene.HangDialog.ToAttactObject = null;
                            LastNoticeTime = 0;
                            hangUpCmd.HangUpPath = false;
                        }
                        return;
                    }
                }

                //到这里的要么没有目标怪物，要么距离大于14
                var allObject = MapControl.Objects.OrderBy(a => Functions.ManhattanDistance(User.CurrentLocation, a.CurrentLocation));
                foreach (var ob in allObject)
                {
                    if (ob == null || ob.Dead || !(ob is MonsterObject))
                        continue;
                    var distance = Functions.ManhattanDistance(User.CurrentLocation, ob.CurrentLocation);
                    if (distance > 30)
                        return;
                    if (distance > 15 && hangUpCmd.HangUpPath && CurrentPath != null && CurrentPath.Count > 0)
                        return;
                    //当白名单开启，则筛选是不是白名单的怪物
                    if (HangDialog.WhiteName != null && HangDialog.WhiteName.Count > 0 && !HangDialog.WhiteName.Contains(ob.Name))
                        continue;
                    if (!HangDialog.DotAttact.Contains(ob.AI))
                    {
                        GameScene.Scene.MapControl.AutoPath = false;
                        var mon = ob as MonsterObject;
                        if (distance < 4)
                        {
                            MapObject.TargetObject = ob;
                            GameScene.Scene.HangDialog.ToAttactObject = null;
                            LastNoticeTime = 0;
                            hangUpCmd.HangUpPath = false;
                            return;
                        }

                        GameScene.Scene.ChatDialog.ReceiveChat(String.Format("自动寻路尝试，目标{0}，坐标{1},{2}，距离{3}", ob.Name, ob.CurrentLocation.X, ob.CurrentLocation.Y, distance), ChatType.Hint);
                        var PathFinder = hangUpCmd.PathFinder;
                        //当地图不同时候，要重置
                        if(PathFinder.Map != GameScene.Scene.MapControl)
                        {
                            PathFinder = new PathFinderD(GameScene.Scene.MapControl);
                        }
#if DEBUG
                        Stopwatch sw = new Stopwatch();
                        sw.Start();
                        
                        List<NodeD> path = PathFinder.IniPath(MapObject.User.CurrentLocation, ob.CurrentLocation).ToList() ;

                        sw.Stop();
                        TimeSpan ts2 = sw.Elapsed;
                        Console.WriteLine("Stopwatch总共花费{0}ms.", ts2.TotalMilliseconds);
#else
                        List<NodeD> path = PathFinder.IniPath(MapObject.User.CurrentLocation, ob.CurrentLocation).ToList() ;
#endif

                        if (path == null || path.Count == 0)
                        {
                            GameScene.Scene.ChatDialog.ReceiveChat("无法找到合适的路线。", ChatType.System);
                        }
                        else
                        {
                            GameScene.Scene.ChatDialog.ReceiveChat(String.Format("自动寻路，目标{0}，坐标{1},{2}，距离{3}", ob.Name, ob.CurrentLocation.X, ob.CurrentLocation.Y, distance), ChatType.Hint);
                            GameScene.Scene.HangDialog.CurrentPath = path;
                            GameScene.Scene.HangDialog.hangUpCmd.HangUpPath = true;
                            GameScene.Scene.HangDialog.ToAttactObject = ob;

                        }
                        return;
                    }
                }
                //当没有任何目标的时候
                if (MapObject.TargetObject == null && GameScene.Scene.HangDialog.ToAttactObject == null && !hangUpCmd.HangUpPath)
                {
                    GameScene.Scene.ChatDialog.ReceiveChat("无法找到可攻击目标，先回到原点", ChatType.Hint);
                    Random random = new Random();
                    List<NodeD> path = null;
                    var cp = MapObject.User.CurrentLocation;
                    for (int i = 0; i < 100; i++)
                    {
                        int x = random.Next(Math.Max(0, cp.X - 50), Math.Min(Width - 1, cp.X + 80));
                        int y = random.Next(Math.Max(0, cp.Y - 50), Math.Min(Height - 1, cp.Y + 80));
                        if (GameScene.Scene.MapControl.EmptyCell(new Point(x, y)))
                        {
                            path = hangUpCmd.PathFinder.IniPath(MapObject.User.CurrentLocation, new Point(x, y)).ToList();
                            if (path != null)
                            {
                                GameScene.Scene.ChatDialog.ReceiveChat("前往坐标。" + x + "," + y, ChatType.System);
                                break;
                            }
                        }
                    }
                    if (path == null || path.Count == 0)
                    {
                        GameScene.Scene.ChatDialog.ReceiveChat("无法找到合适的路线。", ChatType.System);
                        GameScene.Scene.ChatDialog.ReceiveChat("无法回到原点，自动挂机关闭", ChatType.System);
                        //GameScene.Scene.HangDialog.AutoAttack= false;
                    }
                    else
                    {
                        GameScene.Scene.HangDialog.CurrentPath = path;
                        GameScene.Scene.HangDialog.hangUpCmd.HangUpPath = true;
                    }
                }

            }
            finally
            {

            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            var pickName = new List<string>();
            foreach (var str in richTextBox2.Lines)
            {
                if (!String.IsNullOrWhiteSpace(str))
                    pickName.Add(str);
            }
            _pickItemName = pickName.ToArray();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            GameScene.RestartGame();
        }

        private void loadItem_btn_Click(object sender, EventArgs e)
        {
            FileDialog fi = new OpenFileDialog();
            fi.Filter = "拾取列表文件|*.dat";
            try
            {
                if (fi.ShowDialog() == DialogResult.OK)
                {
                    var fileName=fi.FileName;
                    var lines=File.ReadLines(fileName);
                    richTextBox2.Clear();
                    foreach(var line in lines)
                    {
                        if(!String.IsNullOrWhiteSpace(line))
                        {
                            richTextBox2.AppendText(line + "\r\n");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void saveItem_btn_Click(object sender, EventArgs e)
        {
            SaveFileDialog fi = new SaveFileDialog();
            fi.Filter = "拾取列表文件|*.dat";
            try
            {
                if (fi.ShowDialog() == DialogResult.OK)
                {
                    var fileName = fi.FileName;
                    File.WriteAllLines(fileName, richTextBox2.Lines);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}
